package com.generator.server;

import com.generator.util.DbUtil;
import com.generator.util.Field;
import com.generator.util.FreemarkerUtil;
import com.generator.util.ParamsToProperties;
import freemarker.template.TemplateException;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * 我的启动器
 *
 * @author Administrator
 */
public class ServerGenerator {
    //配置文件的路径
    private static String generatorConfigPath = "src/main/resources/generator/generatorConfig.xml";
    //读取配置文件的context节点
    public static Element contextElement;
    static {
        // 只生成配置文件中的第一个table节点
        File file = new File(generatorConfigPath);
        SAXReader reader=new SAXReader();
        //读取xml文件到Document中
        Document doc= null;
        try {
            doc = reader.read(file);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        //获取xml文件的根节点
        Element rootElement=doc.getRootElement();
        //读取context节点
        contextElement = rootElement.element("context");
    }

    //项目-名称
    static String projectName;
    //项目根目录
    static String Path;
    //项目子模块名称，没有则不填
    private static String module;

    //生成的目录
    private static String toControllerPath;
    private static String toServicePath;
    private static String toDtoPath;
    private static String toEnumsPath;
    static {
        Path = ParamsToProperties.getProperties().getProperty("projectSrc");
        module = ParamsToProperties.getProperties().getProperty("module");
        projectName = ParamsToProperties.getProperties().getProperty("projectName");
        //将包名转换为路径
        String controllerPackage = ParamsToProperties.getProperties().getProperty("controllerPackage");
        toControllerPath = Path+"\\"+controllerPackage.replace(".","\\")+"\\";

        String servicePath = ParamsToProperties.getProperties().getProperty("servicePackage");
        toServicePath = Path+"\\"+servicePath.replace(".","\\")+"\\";

        String dtoPath = ParamsToProperties.getProperties().getProperty("dtoPackage");
        toDtoPath = Path+"\\"+dtoPath.replace(".","\\")+"\\";

        String enumsPath = ParamsToProperties.getProperties().getProperty("enumsPackage");
        toEnumsPath = Path+"\\"+enumsPath.replace(".","\\")+"\\";
}


    public static void main(String[] args) throws Exception {
        //创建目录
//        String[] paths = {toControllerPath,toServicePath,toDtoPath,toEnumsPath}; 不生成enums
        String[] paths = {toControllerPath,toServicePath,toDtoPath};
        mkdir(paths);

        //遍历“table”的节点
        Element tableElement;
        Iterator<Element> tables = contextElement.elementIterator("table");
        while (tables.hasNext()){
            tableElement = tables.next();
            //为每个节点生成
            doGenerator(tableElement);
        }
    }


    public static void doGenerator(Element tableElement) throws Exception {
        String Domain = tableElement.attributeValue("domainObjectName");
        String domain = Domain.substring(0, 1).toLowerCase() + Domain.substring(1);
        String tableName = tableElement.attributeValue("tableName");
        String tableNameCn = DbUtil.getTableComment(tableName);

        List<Field> fieldList = DbUtil.getColumnByTableName(tableName);
        Set<String> typeSet = getJavaTypes(fieldList);
        Map<String, Object> map = new HashMap<>();
        map.put("Domain", Domain);
        map.put("domain", domain);
        map.put("tableNameCn", tableNameCn);
        map.put("module", module);
        map.put("projectName",projectName);
        map.put("fieldList", fieldList);
        map.put("typeSet", typeSet);
        //运行的当前字段
        map.put("field", null);

        // 生成dto
        FreemarkerUtil.initConfig("dto.ftl");
        FreemarkerUtil.generator(toDtoPath + Domain + "Dto.java", map);

        // 生成service
        FreemarkerUtil.initConfig("service.ftl");
        FreemarkerUtil.generator(toServicePath + Domain + "Service.java", map);


        // 生成controller
        FreemarkerUtil.initConfig("controller.ftl");
        FreemarkerUtil.generator(toControllerPath + Domain + "Controller.java", map);

        //生成枚举类
        //枚举类可以省略，而用枚举js代替，仅让前端能够识别枚举code所代表的文字意义即可
        //枚举js思路，把每个表里面的枚举生成分别生成为一个json数组，前端直接用数组为下拉框赋值即可
//      creatEnums("enums.ftl",toEnumsPath+Domain,map);//废弃
    }


    /**
     *
     * @param ftlName
     * @param fileName
     * @param map
     */
    private static void creatEnums(String ftlName,String fileName,Map<String, Object> map) throws IOException, TemplateException {
        List<Field> fieldList = (List<Field>) map.get("fieldList");
        for (Field field : fieldList) {
            //判断该字段是否需要枚举
            if(field.getEnums()){
                map.put("field",field);
                //执行代码生成
                FreemarkerUtil.initConfig(ftlName);
                FreemarkerUtil.generator(fileName+field.getNameBigHump()+"Enums.java", map);
            }
        }

    }
    /**
     * 获取所有的Java类型，使用Set去重
     */
    private static Set<String> getJavaTypes(List<Field> fieldList) {
        Set<String> set = new HashSet<>();
        for (int i = 0; i < fieldList.size(); i++) {
            Field field = fieldList.get(i);
            set.add(field.getJavaType());
        }
        return set;
    }
    /**
     * 创建目录
     */
    public static void mkdir(String[] paths){
        //判断目录是否存在，不存在则创建
        for (String path : paths) {
            File file = new File(path);
            if(!file.isDirectory()){ file.mkdirs(); }
        }
    }
}
